#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "link_puc.h"
#include "sql_puc.h"
#include "log_file.h"

void init_link(){
    if(init_sql()){
        printf("已成功连接数据库\n");
    }else{
        printf("数据库连接失败\n");
    }
}

void close_link(){
    if(close_sql()){
        printf("已关闭数据库连接\n");
    }
}

int is_empty(char* value){
    if(value == NULL){
        return 1;
    }
    while(*value != '\n' && *value != '\0'){
        if(*value != ' ' && *value != '\t'){
            return 0;
        }
    }
    return 1;
}

void free_sub(Subject sub){
    if(sub.name != NULL){
        free(sub.name);
        sub.name = NULL;
    }
    if(sub.nature != NULL){
        free(sub.nature);
        sub.nature = NULL;
    }
}

void free_stu(Student stu){
    if(stu.name != NULL){
        free(stu.name);
        stu.name = NULL;
    }
}

void free_subs(Subjects *subs){
    while(subs != NULL){
        free_sub(subs->sub);
        Subjects *s = subs;
        subs = subs->next;
        free(s);
    }
}

void free_stus(Students *stus){
    while(stus != NULL){
        free_stu(stus->stu);
        Students *s = stus;
        stus = stus->next;
        free(s);
    }
}

void free_call(BackCall call){
    if(call.stus != NULL){
        free_stus(call.stus);
        call.stus = NULL;
    }
    if(call.subs != NULL){
        free_subs(call.subs);
        call.subs = NULL;
    }
    if(call.msg != NULL){
        free(call.msg);
        call.msg = NULL;
    }
}

Students *sql_to_stu(MYSQL_RES *res){
    MYSQL_ROW row;
    Students *head, *stu;
    head = (Students*) malloc (sizeof(Students));
    head->next = NULL;
    while((row = mysql_fetch_row(res)) != NULL){
        stu = (Students*) malloc (sizeof(Students));
        stu->stu.id = atoi(row[0]);
        char *buff = (char*) malloc(10 * sizeof(char));
        strcpy(buff, row[1]);
        stu->stu.name = buff;
        stu->stu.num_sub = 0;
        stu->stu.sum_credit = 0;
        stu->next = head->next;
        head->next = stu;
    }
    stu = head -> next;
    while(stu != NULL){
        float sum_credit = 0;
        int num = select_sub_num_stu(stu->stu.id, &sum_credit);
        stu->stu.num_sub = num;
        stu->stu.sum_credit = sum_credit;
        stu = stu->next;
    }
    stu = head->next;
    free(head);
    return stu;
}

Subjects *sql_to_sub(MYSQL_RES *res){
    MYSQL_ROW row;
    Subjects *head, *sub;
    head = (Subjects*) malloc(sizeof(Subjects));
    head->next = NULL;
    while((row = mysql_fetch_row(res)) != NULL){
        sub = (Subjects*) malloc (sizeof(Subjects));
        sub->sub.id = atoi(row[0]);
        char *buff = (char*) malloc(20 * sizeof(char));
        strcpy(buff, row[1]);
        sub->sub.name = buff;
        buff = (char*) malloc(10 * sizeof(char));
        strcpy(buff, row[2]);
        sub->sub.nature = buff;
        sub->sub.period = atoi(row[3]);
        sub->sub.credit = atof(row[4]);
        sub->sub.max_num = atoi(row[5]);
        sub->sub.num = 0;
        sub->next = head->next;
        head->next = sub;
    }
    sub = head -> next;
    while(sub != NULL){
        sub->sub.num = select_stu_num_sub(sub->sub.id);
        sub = sub->next;
    }
    sub = head -> next;
    free(head);
    return sub;
}

BackCall put_stu(Student stu){
    BackCall call;
    if(is_empty(stu.name)){
        call.code = -1;
        call.msg = "姓名不能为空";
        return call;
    }
    int res = insert_stu_sql(stu.id, stu.name);
    if(res == 0){
        call.code = 0;
        call.msg = "插入失败";
        return call;
    }
    call.code = 1;
    call.msg = "插入成功";
    char buff[100];
    sprintf(buff, "添加学生信息, 学号[%d], 姓名[%s]; 结果 : [%s]", stu.id, stu.name, call.msg);
    write_to_log("insert", "student", buff);
    return call;
}

BackCall get_stu_all(){
    MYSQL *sql = select_stu_all_sql();
    MYSQL_RES *res = mysql_use_result(sql);
    Students *stus = sql_to_stu(res);
    mysql_free_result(res);
    BackCall call;
    if(stus == NULL){
        call.code = 0;
        call.msg = "没有学生信息";
    }else{
        call.code = 1;
        call.msg = "获取成功";
    }
    call.stus = stus;
    char buff[100];
    sprintf(buff, "获取所有的学生信息; 结果 : [%s]", call.msg);
    write_to_log("select", "student", buff);
    return call;
}

BackCall get_stu_id(int id){
    MYSQL *sql = select_stu_id_sql(id);
    MYSQL_RES *res = mysql_use_result(sql);
    Students *stus = sql_to_stu(res);
    BackCall call;                                                                                
      if(stus == NULL){
          call.code = 0;
          call.msg = "没有学生信息";
      }else{
          call.code = 1;
          call.msg = "获取成功";
      }   
      call.stus = stus;
      mysql_free_result(res);
      char buff[100];
      sprintf(buff, "获取学号为[%d]的学生信息; 结果 : [%s]", id, call.msg);
      write_to_log("select", "student", buff);
      return call;
}

BackCall get_stu_name(char *name){
    MYSQL *sql = select_stu_name_sql(name);
    MYSQL_RES *res = mysql_use_result(sql);
    Students *stus = sql_to_stu(res);
    BackCall call;                                                                                
    if(stus == NULL){
        call.code = 0;
        call.msg = "没有学生信息";
    }else{
        call.code = 1;
        call.msg = "获取成功";
    }   
    call.stus = stus;
    mysql_free_result(res);
    char buff[100];
    sprintf(buff, "获取姓名为[%s]学生信息; 结果 : [%s]", name, call.msg);
    write_to_log("select", "student", buff);
    return call;
}

BackCall update_stu(Student stu){
    BackCall call;
    if(is_empty(stu.name)){
        call.code = -1;
        call.msg = "姓名不能为空";
        return call;
    }
    int res = update_stu_sql(stu.id, stu.name);
    if(res == 0){
        call.code = 0;
        call.msg = "修改失败";
    }else{
        call.code = 1;
        call.msg = "修改成功";
    }
    char buff[100];
    sprintf(buff, "对学号为[%d]的学生信息进行修改; 结果 : [%s]", stu.id, call.msg);
    write_to_log("update", "student", buff);
    return call;
}

BackCall delete_stu_id(int id){
    BackCall call;

    int res = delete_stu_sql(id);
    if(res == 0){
        call.code = 0;
        call.msg = "删除失败";
    }else{
        call.code = 1;
        call.msg = "删除成功";
    }
    char buff[100];
    sprintf(buff, "删除学号为[%d]的学生信息; 结果 : [%s]", id, call.msg);
    write_to_log("delete", "student", buff);
    return call;
}

BackCall put_sub(Subject sub){
    BackCall call;
    if(is_empty(sub.name)){
        call.msg = "课程名不能为空";
        return call;
    }
    if(is_empty(sub.nature)){
        call.msg = "课程性质不能为空";
        return call;
    }
    if(sub.period == 0){
        call.msg = "课时不能为0";
        return call;
    }
    int res = insert_sub_sql(sub.id, sub.name, sub.nature, sub.period, sub.credit, sub.max_num);
    if(res == 0){
        call.code = 0;
        call.msg = "插入失败";
    }else{
        call.code = 1;
        call.msg = "插入成功";
    }
    char buff[200];
    sprintf(buff, "添加课程信息, 编号[%d], 课程名[%s], 性质[%s], 课时[%d], 学分[%.1f], 最大学生人数[%d]; 结果 : [%s]", sub.id, sub.name, sub.nature, sub.period, sub.credit, sub.max_num, call.msg);
    write_to_log("select", "student", buff);
    return call;
}

BackCall get_sub_all(){
    MYSQL *sql = select_sub_all_sql();
    MYSQL_RES *res = mysql_use_result(sql);
    Subjects *subs = sql_to_sub(res);
    BackCall call;                                                                                
    if(subs == NULL){
        call.code = 0;
        call.msg = "没有课程信息";
    }else{
        call.code = 1;
        call.msg = "获取成功";
    }   
    call.subs = subs;
    mysql_free_result(res);
    char buff[100];
    sprintf(buff, "获取所有的课程信息; 结果 : [%s]", call.msg);
    write_to_log("select", "subject", buff);
    return call;
}

BackCall get_sub_id(int id){
    MYSQL *sql = select_sub_id_sql(id);
    MYSQL_RES *res = mysql_use_result(sql);
    Subjects *subs = sql_to_sub(res);
    BackCall call;                                                                                
    if(subs == NULL){
        call.code = 0;
        call.msg = "没有课程信息";
    }else{
        call.code = 1;
        call.msg = "获取成功";
    }   
    call.subs = subs;
    mysql_free_result(res);
    char buff[100];
    sprintf(buff, "获取课程编号为[%d]的课程信息; 结果 : [%s]", id, call.msg);                                   
    write_to_log("select", "subject", buff);
    return call;
}

BackCall update_sub(Subject sub){
    BackCall call;
    if(is_empty(sub.name)){
        call.msg = "课程名不能为空";
        return call;
    }
    if(is_empty(sub.nature)){
        call.msg = "课程性质不能为空";
        return call;
    }
    if(sub.period == 0){
        call.msg = "课时不能为0";
        return call;
    }
    int res = update_sub_sql(sub.id, sub.name, sub.nature, sub.period, sub.credit, sub.max_num);
    if(res == 0){
        call.code = 0;
        call.msg = "修改失败";
    }else{
        call.code = 1;
        call.msg = "修改成功";
    }
    char buff[100];
    sprintf(buff, "对编号为[%d]的课程信息进行修改; 结果 : [%s]", sub.id, call.msg);
    write_to_log("update", "subject", buff);
    return call;

}

BackCall delete_sub_id(int id){
    BackCall call;
    int res = delete_sub_sql(id);
    if(res == 0){
        call.code = 0;
        call.msg = "删除失败";
    }else{
        call.code = 1;
        call.msg = "删除成功";
    }
    char buff[100];
    sprintf(buff, "删除编号为[%d]的课程信息; 结果 : [%s]", id, call.msg);
    write_to_log("delete", "subject", buff);
    return call;
}

BackCall put_sub_by_stu(Student stu, Subject sub){
    int res = insert_stu_sub(stu.id, sub.id);
    BackCall call;
    if(res == 0){
        call.code = 0;
        call.msg = "添加失败";
        return call;
    }
    call.code = 1;
    call.msg = "添加成功";
    char buff[100];
    sprintf(buff, "学号为[%d]的学生添加编号为[%d]的课程; 结果 : [%s]", stu.id, sub.id, call.msg);
    write_to_log("update", "student-subject", buff);
    return call;
}

BackCall get_sub_by_stu(Student stu){
    MYSQL *sql = select_sub_by_stu_sql(stu.id);
    MYSQL_RES *res = mysql_use_result(sql);
    Subjects *subs = sql_to_sub(res);
    BackCall call;                                                                                
    if(subs == NULL){
    call.code = 0;
        call.msg = "没有课程信息";
    }else{
        call.code = 1;
        call.msg = "获取成功";
    }   
    call.subs = subs;
    mysql_free_result(res);
    char buff[100];
    sprintf(buff, "获取学号为[%d]的学生已选的所有的课程信息; 结果 : [%s]", stu.id, call.msg);
    write_to_log("select", "subject", buff);
    return call;
}

BackCall get_sub_by_not_stu(int id){
    MYSQL *sql = slelect_sub_by_not_stu_sql(id);
    MYSQL_RES *res = mysql_use_result(sql);
    Subjects *subs = sql_to_sub(res);
    BackCall call;                                                                                
    if(subs == NULL){
    call.code = 0;
        call.msg = "没有课程信息";
    }else{
        call.code = 1;
        call.msg = "获取成功";
    }   
    call.subs = subs;
    mysql_free_result(res);
    char buff[100];
    sprintf(buff, "获取所有没有选取编号为[%d]的课程的学生数据; 结果 : [%s]", id, call.msg);
    write_to_log("select", "subject", buff);
    return call;

}

BackCall get_stu_by_sub(Subject sub){
    MYSQL *sql = select_stu_by_sub_sql(sub.id);
    MYSQL_RES *res = mysql_use_result(sql);
    Students *stus = sql_to_stu(res);
    mysql_free_result(res);
    BackCall call;
    if(stus == NULL){
        call.code = 0;
        call.msg = "没有学生信息";
    }else{
        call.code = 1;
        call.msg = "获取成功";
    }
    call.stus = stus;
    char buff[100];
    sprintf(buff, "获取编号为[%d]的课程的所有学生; 结果 : [%s]", sub.id, call.msg);
    write_to_log("select", "subject", buff);
    return call;
}

BackCall remove_sub_by_stu(Student stu, Subject sub){
    int res = delete_stu_sub(stu.id, sub.id);
    BackCall call;
    if(res == 0){
        call.code = 0;
        call.msg = "删除失败";
        return call;
    }
    call.code = 1;
    call.msg = "删除成功";
    char buff[100];
    sprintf(buff, "学号为[%d]的学生退出编号为[%d]的课程; 结果 : [%s]", stu.id, sub.id, call.msg);
    write_to_log("update", "student-subject", buff);
    return call;
}

